/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package questionbook.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.model.vocabulary.RDFS;
import questionbook.Configuration.QuestionbookConfiguration;
import questionbook.exception.IndividualAlreadyExistsException;
import questionbook.manager.StoreManager;
import questionbook.model.Answer;
import questionbook.model.AnswerClass;
import questionbook.model.AnswerType;
import questionbook.model.Person;
import questionbook.model.Question;
import questionbook.service.common.GenericServiceImpl;
import questionbook.standard.Qbook;

/**
 *
 * @author stefanstift
 */
public class AnswerServiceBean extends GenericServiceImpl implements AnswerService{

    private PersonService personService = new PersonServiceBean();

    public void answer(Answer a, Question q) {

        this.storeManager.getStore().add(a.getUri(), RDF.TYPE, Qbook.getInstance().getAnswerURI());
        this.storeManager.getStore().add(a.getAnswerer().getUri(), Qbook.getInstance().getSaysURI(), a.getUri());
        this.storeManager.getStore().add(q.getUri(), a.getAnswerType().getUri(), a.getUri());
        this.storeManager.getStore().add(a.getUri(), Qbook.getInstance().getCreatedAtURI(), a.getCreatedAtLiteral());


        if(a.getText() != null  && !a.getText().isEmpty())
            this.storeManager.getStore().add(a.getUri(), RDFS.LABEL, a.getTextLiteral());

    }

    public Answer getIdentifiedAnswer() throws IndividualAlreadyExistsException{

        int i = 0;
        String answerBase = "/qbAnswer";
        Date d = new Date();
        String timestamp = Long.toString(d.getTime());
        String id = QuestionbookConfiguration.getInstance().getBaseURL() + answerBase + timestamp;
        URI uri = this.storeManager.getStore().getURIref(id);

        List check = this.storeManager.getStore().tuplePattern(uri, null, null);

        while(check != null || !check.isEmpty())
        {
            if(i == 10)
            {
                break;
            }

            d = new Date();
            timestamp = Long.toString(d.getTime());
            id = QuestionbookConfiguration.getInstance().getBaseURL() + answerBase + timestamp;
            uri = StoreManager.getInstance().getStore().getURIref(id);

            check = this.storeManager.getStore().tuplePattern(uri, null, null);

            i++;
        }

        if(check == null || check.isEmpty())
        {
            Answer a = new Answer(uri);
            a.setCreatedAt(new Date());
            return a;
        }

        throw new IndividualAlreadyExistsException("Tried to create Answer with URI " + id + " - but it already exists in the Store");
    }

  

    public void delete(Answer a) {

         this.storeManager.getStore().removeTuplePattern(a.getUri(), null, null);
         this.storeManager.getStore().removeTuplePattern(null, null, a.getUri());
    }

    public List<Answer> getByQuestion(Question q) {

        List<Answer> answerList = new ArrayList<Answer>();

        List<Map> resultList = this.storeManager.getStore().runSPARQL("SELECT ?answer ?text ?answerer ?createdAt"
                + " WHERE { ?answer <" + RDF.TYPE + "> <" + Qbook.getInstance().getAnswerURI() +  "> ."
                + " ?answer <" + RDFS.LABEL + "> ?text ."
                + " ?answerer <" + Qbook.getInstance().getSaysURI()+ "> ?answer ."
                + " <" + q.getUri().stringValue() + "> <" + Qbook.getInstance().getAnswersURI()+ "> ?answer ."
                + " ?answer <" + Qbook.getInstance().getCreatedAtURI() + "> ?createdAt "
                + "}");


        for(Map m : resultList)
        {
            Answer a = new Answer(((Value) m.get("answer")).stringValue());
            a.setText(((Value) m.get("text")).stringValue());
            a.setCreatedAt(((Value) m.get("createdAt")).stringValue());

            URI answerer = this.storeManager.getStore().getURIref(((Value) m.get("answerer")).stringValue());
            a.setAnswerer(this.personService.get(answerer));

            this.loadAnswerType(q, a);
            this.loadAnswerClass(a);
            answerList.add(a);
        }

        return answerList;
    }

    public List<Answer> getByPerson(Person p) {

        List<Answer> answerList = new ArrayList<Answer>();

        List<Map> resultList = this.storeManager.getStore().runSPARQL("SELECT ?answer ?answerer ?text ?question ?createdAt"
                + " WHERE { ?answer <" + RDF.TYPE + "> <" + Qbook.getInstance().getAnswerURI() +  "> ."
                + " ?answer <" + RDFS.LABEL + "> ?text ."
                + " ?answerer <" + Qbook.getInstance().getSaysURI()+ "> ?answer ."
                + " <" + p.getUri() + "> <" + Qbook.getInstance().getSaysURI()+ "> ?answer ."
                + " ?question <" + Qbook.getInstance().getAnswersURI()+ "> ?answer ."
                + " ?answer <" + Qbook.getInstance().getCreatedAtURI() + "> ?createdAt "
                + "}");


        for(Map m : resultList)
        {
            Answer a = new Answer(((Value) m.get("answer")).stringValue());
            a.setText(((Value) m.get("text")).stringValue());
            a.setCreatedAt(((Value) m.get("createdAt")).stringValue());

            a.setAnswerer(p);
            
            Question q = new Question(((Value) m.get("question")).stringValue());

            this.loadAnswerType(q, a);
            this.loadAnswerClass(a);
            answerList.add(a);
        }

        return answerList;
    }

    public void loadAnswerType(Question question, Answer answer)
    {
        List<Statement> res = this.storeManager.getStore().tuplePattern(question.getUri(), null, answer.getUri());

        for(Statement s : res)
        {
            AnswerType a =  Qbook.getInstance().getAnswerType(s.getPredicate().stringValue());

            if(a != null)
                answer.setAnswerType(a);
        }
    }

    public void loadAnswerClass(Answer answer)
    {
        List<Statement> res = this.storeManager.getStore().tuplePattern(answer.getUri(), RDF.TYPE, null);

        for(Statement s : res)
        {
            AnswerClass a =  Qbook.getInstance().getAnswerClass(s.getObject().stringValue());

            if(a != null)
                answer.setAnswerClass(a);
        }
    }

    public void removeClassification(Answer a)
    {
        this.storeManager.getStore().removeTuplePattern(a.getUri(), RDF.TYPE, null);
    }

    public void updateClassification(Answer a)
    {
        this.storeManager.getStore().add(a.getUri(), RDF.TYPE, Qbook.getInstance().getAnswerClassURI(a.getAnswerClass()));

    }

   

  
}
